package com.ff.kvm.mall.service.impl;

import com.ff.kvm.common.dv.order.*;
import com.ff.kvm.common.eunm.ExpressTypeEnum;
import com.ff.kvm.common.eunm.OrderStatusEnum;
import com.ff.kvm.common.eunm.OrderTypeEnum;
import com.ff.kvm.common.eunm.StatusEnum;
import com.ff.kvm.common.util.Constants;
import com.ff.kvm.common.util.ConvertUtil;
import com.ff.kvm.common.util.MyUtil;
import com.ff.kvm.common.util.UuidUtil;
import com.ff.kvm.common.vo.PageResult;
import com.ff.kvm.common.vo.Response;
import com.ff.kvm.dao.mapper.OrderMapper;
import com.ff.kvm.dao.model.*;
import com.ff.kvm.mall.service.*;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private RedisService redisService;

    @Autowired
    private OrderMapper orderMapper;


    @Autowired
    private OrderItemsService orderItemsService;

    @Autowired
    private OrderExpressService orderExpressService;


    @Autowired
    private OrderPriceService orderPriceService;

    @Autowired
    private PaymentService paymentService;

    @Autowired
    private AddressService addressService;

    @Override
    public Order createOrder(int userId,int addressId,int expressType,String remark,int type) {
        Order order = new Order();
        order.setUserId(userId);
        order.setNo(getOrderNO());
        order.setStatus(OrderStatusEnum.PAYMENT.type());
        order.setAddressId(addressId);
        order.setCreateTime(new Date());
        order.setExpressType(expressType);
        order.setType(type);
        order.setRemark(remark);
        orderMapper.insert(order);

        orderExpressService.createOrderExpress(order.getId(),order.getNo(),expressType);

        return order;
    }

    @Override
    public Response<PageResult<OrderDV>> orderList(OrderPageDV orderPageDV) {
        Response<PageResult<OrderDV>> response = new Response<>();
        PageResult<OrderDV> result = new PageResult<>();
        int pageSize = Integer.valueOf(redisService.getCache(Constants.PAGE_SIZE));
        Page page = PageHelper.startPage(orderPageDV.getPageNum(),pageSize);
        List<Order> list = orderMapper.findOrderListByStatus(orderPageDV.getUserId(),orderPageDV.getStatus());
        List<OrderDV> listDV = new ArrayList<>();
        for (Order order : list){
            List<OrderItemsDV> itemsListDV = new ArrayList<>();
            List<OrderItems> itemsList = orderItemsService.findOrderItemsByOrderId(order.getId());
            for(OrderItems orderItems : itemsList){
                OrderItemsDV orderItemsDV = ConvertUtil.convert(orderItems,OrderItemsDV.class);
                itemsListDV.add(orderItemsDV);
            }

            OrderDV orderDV = new OrderDV();
            orderDV.setId(order.getId());
            orderDV.setNo(order.getNo());
            orderDV.setStatus(order.getStatus());
            orderDV.setStatusDes(OrderStatusEnum.getName(order.getStatus()));
            orderDV.setQuantity(itemsList.size());
            orderDV.setItems(itemsListDV);
            orderDV.setCreateTime(MyUtil.formatDateYMDhms(order.getCreateTime()));
            OrderPrice orderPrice = orderPriceService.findOrderPriceByOrderId(order.getId());
            orderDV.setPostFee(orderPrice.getPostFee());
            orderDV.setAmount(orderPrice.getAmount());
            orderDV.setTotal(orderPrice.getTotal());
            listDV.add(orderDV);
        }
        result.setData(listDV);
        result.setTotal(page.getTotal());
        result.setPageSize(pageSize);
        response.setData(result);
        response.setCode(StatusEnum.SUCCESS.code());
        response.setMsg(StatusEnum.SUCCESS.description());
        return response;
    }

    @Override
    public Response<OrderDetailDV> orderDetail(int orderId) {
        Response<OrderDetailDV> response = new Response<>();
        Order order = orderMapper.selectByPrimaryKey(orderId);
        OrderPrice orderPrice = orderPriceService.findOrderPriceByOrderId(orderId);
        OrderDetailDV orderDetailDV = new OrderDetailDV();
        orderDetailDV.setNo(order.getNo());
        orderDetailDV.setOrderId(orderId);
        orderDetailDV.setStatus(order.getStatus());
        orderDetailDV.setStatusDes(OrderStatusEnum.getName(order.getStatus()));
        orderDetailDV.setTotal(orderPrice.getTotal());
        orderDetailDV.setAmount(orderPrice.getAmount());
        orderDetailDV.setPostFee(orderPrice.getPostFee());
        orderDetailDV.setCreateTime(MyUtil.formatDateYMDhms(order.getCreateTime()));
        Date payTime = paymentService.getPayTime(orderId);
        orderDetailDV.setPayTime(MyUtil.formatDateYMDhms(payTime));
        Date sendTime = orderExpressService.getSendTime(orderId);
        Address address = addressService.findAddressById(order.getAddressId());
        orderDetailDV.setSendTime(MyUtil.formatDateYMDhms(sendTime));
        orderDetailDV.setRecName(address.getName());
        orderDetailDV.setMobile(address.getMobile());
        StringBuffer sb = new StringBuffer();
        sb.append(address.getProvince());
        sb.append(address.getCity());
        sb.append(address.getArea());
        sb.append(address.getDetail());
        orderDetailDV.setAddress(sb.toString());
        if(order.getType() == OrderTypeEnum.NORMAL.type()){
            orderDetailDV.setItems(orderItemsService.getItemsDV(order.getId()));
        }else if(order.getType() == OrderTypeEnum.GIFTBOX.type()){
            orderDetailDV.setItems(orderItemsService.getGiftBoxItemsDV(order.getId()));
        }
        response.setData(orderDetailDV);
        response.setCode(StatusEnum.SUCCESS.code());
        response.setMsg(StatusEnum.SUCCESS.description());
        return response;
    }

    @Override
    public Response<OrderExpressDV> expressDetail(int orderId) {
        Response<OrderExpressDV> response = new Response<>();
        OrderExpressDV orderExpressDV = new OrderExpressDV();
        OrderExpress orderExpress = orderExpressService.findOrderExpressByOrderId(orderId);
        orderExpressDV.setExpressName(orderExpress.getExpressName());
        orderExpressDV.setExpressNo(orderExpress.getExpressNo());
        orderExpressDV.setExpressStatus(orderExpress.getExpressStatus());
        orderExpressDV.setSendTime(MyUtil.formatDateYMDhms(orderExpress.getSendTime()));
        orderExpressDV.setSignTime(MyUtil.formatDateYMDhms(orderExpress.getSignTime()));
        response.setData(orderExpressDV);
        response.setCode(StatusEnum.SUCCESS.code());
        response.setMsg(StatusEnum.SUCCESS.description());
        return response;
    }

    @Override
    public Order findOrderById(int orderId) {
        return orderMapper.selectByPrimaryKey(orderId);
    }

    @Override
    public Integer updateOrder(Order order) {
        return orderMapper.updateByPrimaryKey(order);
    }

    private String getOrderNO() {
        return "KVM"+UuidUtil.nowDateUuid();
    }

    @Override
    public int getOrderIdByOrderNo(String orderNo) {
        return orderMapper.getOrderIdByOrderNo(orderNo);
    }

    @Transactional
    @Override
    public Response<Boolean> signOrder(int userId, int orderId) {
        Response<Boolean> response = new Response<>();
        int rt = orderMapper.updateOrderStatus(userId,orderId,OrderStatusEnum.COMPLETE.type());
        int rt2 = orderExpressService.sign(orderId);
        if(rt ==0 || rt2 == 0){
            response.setCode(StatusEnum.FAIL.code());
            response.setMsg(StatusEnum.FAIL.description());
            response.setData(false);
            return response;
        }
        response.setCode(StatusEnum.SUCCESS.code());
        response.setMsg(StatusEnum.SUCCESS.description());
        response.setData(true);
        return response;
    }

    @Override
    public Order findOrderByNo(String orderNo) {

        return orderMapper.findOrderByNo(orderNo);
    }

    @Override
    public int updateStatus(int userId,int orderId, int status) {
        return orderMapper.updateOrderStatus(userId,orderId,status);
    }

    @Transactional
    @Override
    public Response<Boolean> cancleOrder(int userId, int orderId) {
        Response<Boolean> response = new Response<>();
        orderMapper.updateOrderStatus(userId,orderId,OrderStatusEnum.CANCLE.type());
        response.setCode(StatusEnum.SUCCESS.code());
        response.setMsg(StatusEnum.SUCCESS.description());
        response.setData(true);
        return response;
    }
}
